{

(*
This file is part of the Lustre reader

* Copyright (c) 2010, Nicola Camuffo.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*     * Redistributions of source code must retain the above copyright
*       notice, this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in the
*       documentation and/or other materials provided with the distribution.
*     * Neither the name of Nicola Camuffo, nor the
*       names of its contributors may be used to endorse or promote products
*       derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ''AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*)


open Lusparser

let linenum = Filepos.linenum
let linepos = Filepos.linepos

}

rule token = parse

  (* files *)
  "include" { INCLUDE }

(* packages *)
  | "package" { PACKAGE }
  | "end" { END }
  | "body" { BODY }
  | "uses" { USES }
  | "provides" { PROVIDES }
  | "model" { MODEL }
  | "needs" { NEEDS }
  | "is" { IS }

(* comments *)
  |  "/*" ([^'*']* ('*' [^'/'])?)* "*/" {
      String.iter (fun x -> if x == '\n' then incr linenum) (Lexing.lexeme lexbuf);
      token lexbuf}
  | "--" [^'%'] [^'\n']* { token lexbuf }

(* constant definitions *)
  | "const" { CONST }

(* type definitions *)
  | "type" { TYPE }
  | "struct" { STRUCT }
  | "enum" { ENUM }
  | "of" { OF }
  | '^' { ARRAYOF }
  | "int" { INT }
  | "real" { REAL }
  | "bool" { BOOL }

(* node & function definitions *)
  | "extern" { EXTERN }
  | "node" { NODE }
  | "function" { FUNCTION }
  | "returns" { RETURNS }
  | "var" { VAR }
  | "let" { LET }
  | "tel" { TEL }

(* tuple selection *)	
  | "step" { STEP }
  | ".." { DOUBLEDOT }
	
(* binary operators *)
  | '-' { MINUS }
  | '+' { PLUS }
  | '/' { DIV }
  | '*' { MULT }
  | "div" { INTDIV }
  | "mod" { MOD }
  | "and" { AND }
  | "xor" { XOR }
  | "or" { OR }
  | "=>" { IMPL }
  | "<=" { LTE }
  | ">=" { GTE }
  | '<' { LT }
  | '>' { GT }
  | '=' { EQ }
  | "<>" { NEQ }

(* unary operators *)
  | "mirror" { MIRROR }
  | "not" { NOT }

(* n-ary operators *)
  | '#' { EXCL }
  | "nor" { NOR }

(* temporal operators *)
  | "pre" { PRE }
  | "->" { ARROW }
  | "when" { WHEN }
  | "current" { CURRENT }

(* conditional operators *)
  | "if" { IF }
  | "then" { THEN }
  | "else" { ELSE }
  | "with" { WITH }

(*  values *)
  | "true" { TRUE }
  | "false" { FALSE }
  | ['0'-'9']+ '.' ['0'-'9']+ { FLOAT(Lexing.lexeme lexbuf) }
  | ['0'-'9']+ { NUM(Lexing.lexeme lexbuf) }
  | ['a'-'z' 'A'-'Z' '_'] ['a'-'z' 'A'-'Z' '_' '0'-'9']* { SYM(Lexing.lexeme lexbuf) }
  | "--INCL--" { STRING } (* all chars except '\n' and '%' and between '"': SET RIGHT *)

(*  assertions *)
  | "assert" { ASSERT }

(*  symbols *)
  | ';' { SEMICOLON }
  | '{' { LBRACE }
  | '}' { RBRACE }
  | '[' { LSQBRACKET }
  | ']' { RSQBRACKET }
  | '(' { LPAREN }
  | ')' { RPAREN }
  | ':' { COLON }
  | "::" { DOUBLECOLON }
  | ',' { COMMA }
  | '.' { DOT }
  | '%' { PERCENT }
  | "<<" { LGUILLEMET }
  | ">>" { RGUILLEMET }

(*  SCADE *)
  | "--%METAPROPERTY" [^';']* { METAPROPERTY(
      let s = Lexing.lexeme lexbuf in
      String.sub s 16 ((String.length s) - 16)
     ) }  
  | "--%MAIN" [^'\n']* { MAIN_NODE }
  | "_TO_" ['a'-'z' 'A'-'Z' '_'] ['a'-'z' 'A'-'Z' '_' '0'-'9']* { CONVERT_TO(Lexing.lexeme lexbuf) }
  | "_FROM_" ['a'-'z' 'A'-'Z' '_'] ['a'-'z' 'A'-'Z' '_' '0'-'9']* { CONVERT_FROM(Lexing.lexeme lexbuf) }
  | "--%PROPERTY" { PROPERTY }
  | "condact" { CONDACT }
  | "condact_reset" { CONDACT }
  | "fby" { FBY }

  | eof { EOF_TOK }
  | '\n' {incr linenum; linepos := Lexing.lexeme_start lexbuf; token lexbuf}
  | _ { token lexbuf }
 